<html>
<head>
<title>main.py</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.s0 { color: #cc7832;}
.s1 { color: #a9b7c6;}
.s2 { color: #6897bb;}
.s3 { color: #808080;}
.s4 { color: #6a8759;}
.s5 { color: #629755; font-style: italic;}
</style>
</head>
<body bgcolor="#2b2b2b">
<table CELLSPACING=0 CELLPADDING=5 COLS=1 WIDTH="100%" BGCOLOR="#606060" >
<tr><td><center>
<font face="Arial, Helvetica" color="#000000">
main.py</font>
</center></td></tr></table>
<pre><span class="s0">import </span><span class="s1">tkinter </span><span class="s0">as </span><span class="s1">tk</span>
<span class="s0">from </span><span class="s1">PIL </span><span class="s0">import </span><span class="s1">Image</span><span class="s0">, </span><span class="s1">ImageTk</span>
<span class="s0">import </span><span class="s1">random</span>
<span class="s0">import </span><span class="s1">math</span>

<span class="s1">Dir = {</span>
    <span class="s2">0</span><span class="s1">: (</span><span class="s2">1</span><span class="s0">, </span><span class="s2">0</span><span class="s1">)</span><span class="s0">,  </span><span class="s3"># 向右</span>
    <span class="s2">1</span><span class="s1">: (</span><span class="s2">0</span><span class="s0">, </span><span class="s1">-</span><span class="s2">1</span><span class="s1">)</span><span class="s0">,  </span><span class="s3"># 向上</span>
    <span class="s2">2</span><span class="s1">: (-</span><span class="s2">1</span><span class="s0">, </span><span class="s2">0</span><span class="s1">)</span><span class="s0">,  </span><span class="s3"># 向左</span>
    <span class="s2">3</span><span class="s1">: (</span><span class="s2">0</span><span class="s0">, </span><span class="s2">1</span><span class="s1">)  </span><span class="s3"># 向下</span>
<span class="s1">}</span>
<span class="s1">zidan_list = []</span>
<span class="s3"># Boss 图像路径</span>
<span class="s1">BOSS = [</span>
    <span class="s4">&quot;F:/python2048/0星怪兽.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/一星怪兽.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/二星怪兽.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/三星怪兽.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/四星怪兽.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/五星怪兽.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/怪兽一号.png&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/怪兽二号.png&quot;</span>
<span class="s1">]</span>


<span class="s0">class </span><span class="s1">Zidan:</span>
    <span class="s0">def </span><span class="s1">__init__(self</span><span class="s0">, </span><span class="s1">x</span><span class="s0">, </span><span class="s1">y</span><span class="s0">, </span><span class="s1">dir_x</span><span class="s0">, </span><span class="s1">dir_y):</span>
        <span class="s1">self.x = x</span>
        <span class="s1">self.y = y</span>
        <span class="s1">self.dir_x = dir_x  </span><span class="s3"># 方向向量 x 分量</span>
        <span class="s1">self.dir_y = dir_y  </span><span class="s3"># 方向向量 y 分量</span>
        <span class="s1">self.speed = </span><span class="s2">10  </span><span class="s3"># 子弹速度</span>
        <span class="s1">self.path = </span><span class="s4">'F:/python2048/雷电球.jpg'</span>
        <span class="s1">self.character_photo = </span><span class="s0">None</span>
        <span class="s1">self.image_item = </span><span class="s0">None</span>
        <span class="s1">self.is_alive = </span><span class="s0">True</span>
        <span class="s1">self.create_on_canvas(canvas)  </span><span class="s3"># 初始化时创建图像</span>

    <span class="s0">def </span><span class="s1">run(self):</span>
        <span class="s5">&quot;&quot;&quot;更新子弹的位置&quot;&quot;&quot;</span>
        <span class="s1">self.x += self.dir_x * self.speed</span>
        <span class="s1">self.y += self.dir_y * self.speed</span>

        <span class="s3"># 边界检测</span>
        <span class="s0">if </span><span class="s1">(self.x &lt; </span><span class="s2">0 </span><span class="s0">or </span><span class="s1">self.x &gt;= cols * cell_width </span><span class="s0">or</span>
                <span class="s1">self.y &lt; </span><span class="s2">0 </span><span class="s0">or </span><span class="s1">self.y &gt;= rows * cell_height):</span>
            <span class="s1">self.is_alive = </span><span class="s0">False</span>
        <span class="s0">else</span><span class="s1">:  </span><span class="s3"># 更新画布位置</span>
            <span class="s1">canvas.coords(self.image_item</span><span class="s0">, </span><span class="s1">self.x</span><span class="s0">, </span><span class="s1">self.y)</span>

    <span class="s0">def </span><span class="s1">update_image(self):</span>
        <span class="s1">character_image = Image.open(self.path)</span>
        <span class="s1">character_image = character_image.resize((cell_width // </span><span class="s2">2</span><span class="s0">, </span><span class="s1">cell_height // </span><span class="s2">2</span><span class="s1">))</span>
        <span class="s1">self.character_photo = ImageTk.PhotoImage(character_image)</span>

    <span class="s0">def </span><span class="s1">create_on_canvas(self</span><span class="s0">, </span><span class="s1">canvas):</span>
        <span class="s1">self.update_image()</span>
        <span class="s1">self.image_item = canvas.create_image(self.x</span><span class="s0">, </span><span class="s1">self.y</span><span class="s0">, </span><span class="s1">anchor=</span><span class="s4">&quot;nw&quot;</span><span class="s0">, </span><span class="s1">image=self.character_photo)</span>

    <span class="s0">def </span><span class="s1">attackboss(self):</span>
        <span class="s5">&quot;&quot;&quot;子弹与Boss碰撞检测&quot;&quot;&quot;</span>
        <span class="s1">bullet_grid_x = self.x // cell_width</span>
        <span class="s1">bullet_grid_y = self.y // cell_height</span>

        <span class="s0">for </span><span class="s1">boss </span><span class="s0">in </span><span class="s1">boss_list[:]:</span>
            <span class="s1">boss_grid_x = boss.x // cell_width</span>
            <span class="s1">boss_grid_y = boss.y // cell_height</span>

            <span class="s0">if </span><span class="s1">bullet_grid_x == boss_grid_x </span><span class="s0">and </span><span class="s1">bullet_grid_y == boss_grid_y:</span>
                <span class="s3"># 生成新Boss并升级角色</span>
                <span class="s1">boss_list.remove(boss)</span>
                <span class="s1">boss.delete_from_canvas(canvas)</span>
                <span class="s1">new_boss = generate_random_boss(character_p1.grade)</span>
                <span class="s1">new_boss.update_image()</span>
                <span class="s1">new_boss.create_on_canvas(canvas)</span>
                <span class="s1">boss_list.append(new_boss)</span>
                <span class="s1">self.is_alive = </span><span class="s0">False  </span><span class="s3"># 子弹消失</span>
                <span class="s0">break</span>


<span class="s0">def </span><span class="s1">on_canvas_click(event):</span>
    <span class="s5">&quot;&quot;&quot;鼠标点击事件处理&quot;&quot;&quot;</span>
    <span class="s1">click_x = event.x</span>
    <span class="s1">click_y = event.y</span>
    <span class="s1">x = character_p1.x + cell_width // </span><span class="s2">2  </span><span class="s3"># 角色中心 x</span>
    <span class="s1">y = character_p1.y + cell_height // </span><span class="s2">2  </span><span class="s3"># 角色中心 y</span>

    <span class="s3"># 计算方向向量</span>
    <span class="s1">dx = click_x - x</span>
    <span class="s1">dy = click_y - y</span>
    <span class="s1">distance = math.sqrt(dx ** </span><span class="s2">2 </span><span class="s1">+ dy ** </span><span class="s2">2</span><span class="s1">)</span>

    <span class="s0">if </span><span class="s1">distance == </span><span class="s2">0</span><span class="s1">:</span>
        <span class="s0">return  </span><span class="s3"># 避免除以零</span>

    <span class="s3"># 归一化方向向量</span>
    <span class="s1">dir_x = dx / distance</span>
    <span class="s1">dir_y = dy / distance</span>

    <span class="s3"># 创建子弹（从角色中心发射）</span>
    <span class="s1">zidan = Zidan(x-</span><span class="s2">25</span><span class="s0">, </span><span class="s1">y-</span><span class="s2">25</span><span class="s0">, </span><span class="s1">dir_x</span><span class="s0">, </span><span class="s1">dir_y)</span>
    <span class="s1">zidan_list.append(zidan)</span>


<span class="s0">class </span><span class="s1">Character:</span>
    <span class="s0">def </span><span class="s1">__init__(self</span><span class="s0">, </span><span class="s1">x</span><span class="s0">, </span><span class="s1">y</span><span class="s0">, </span><span class="s1">form):</span>
        <span class="s1">self.x = x</span>
        <span class="s1">self.y = y</span>
        <span class="s1">self.form = form</span>
        <span class="s1">self.grade = </span><span class="s2">0</span>
        <span class="s1">self.character_photo = </span><span class="s0">None</span>
        <span class="s1">self.character_image_item = </span><span class="s0">None</span>
        <span class="s1">self.update_image()</span>
        <span class="s1">self.create_on_canvas(canvas)</span>

    <span class="s0">def </span><span class="s1">update_image(self):</span>
        <span class="s1">character_image = Image.open(self.form[self.grade])</span>
        <span class="s1">character_image = character_image.resize((cell_width</span><span class="s0">, </span><span class="s1">cell_height))</span>
        <span class="s1">self.character_photo = ImageTk.PhotoImage(character_image)</span>

    <span class="s0">def </span><span class="s1">move(self</span><span class="s0">, </span><span class="s1">event):</span>
        <span class="s1">key = event.keysym</span>
        <span class="s1">new_x</span><span class="s0">, </span><span class="s1">new_y = self.x</span><span class="s0">, </span><span class="s1">self.y</span>

        <span class="s0">if </span><span class="s1">key </span><span class="s0">in </span><span class="s1">(</span><span class="s4">&quot;Up&quot;</span><span class="s0">, </span><span class="s4">&quot;w&quot;</span><span class="s1">) </span><span class="s0">and </span><span class="s1">self.y &gt; </span><span class="s2">0</span><span class="s1">:</span>
            <span class="s1">new_y -= cell_height</span>
        <span class="s0">elif </span><span class="s1">key </span><span class="s0">in </span><span class="s1">(</span><span class="s4">&quot;Down&quot;</span><span class="s0">, </span><span class="s4">&quot;s&quot;</span><span class="s1">) </span><span class="s0">and </span><span class="s1">self.y &lt; (rows - </span><span class="s2">1</span><span class="s1">) * cell_height:</span>
            <span class="s1">new_y += cell_height</span>
        <span class="s0">elif </span><span class="s1">key </span><span class="s0">in </span><span class="s1">(</span><span class="s4">&quot;Left&quot;</span><span class="s0">, </span><span class="s4">&quot;a&quot;</span><span class="s1">) </span><span class="s0">and </span><span class="s1">self.x &gt; </span><span class="s2">0</span><span class="s1">:</span>
            <span class="s1">new_x -= cell_width</span>
        <span class="s0">elif </span><span class="s1">key </span><span class="s0">in </span><span class="s1">(</span><span class="s4">&quot;Right&quot;</span><span class="s0">, </span><span class="s4">&quot;d&quot;</span><span class="s1">) </span><span class="s0">and </span><span class="s1">self.x &lt; (cols - </span><span class="s2">1</span><span class="s1">) * cell_width:</span>
            <span class="s1">new_x += cell_width</span>

        <span class="s3"># 更新位置</span>
        <span class="s1">self.x</span><span class="s0">, </span><span class="s1">self.y = new_x</span><span class="s0">, </span><span class="s1">new_y</span>
        <span class="s1">canvas.coords(self.character_image_item</span><span class="s0">, </span><span class="s1">self.x</span><span class="s0">, </span><span class="s1">self.y)</span>
        <span class="s1">self.attackboss()</span>

    <span class="s0">def </span><span class="s1">create_on_canvas(self</span><span class="s0">, </span><span class="s1">canvas):</span>
        <span class="s1">self.character_image_item = canvas.create_image(self.x</span><span class="s0">, </span><span class="s1">self.y</span><span class="s0">, </span><span class="s1">anchor=</span><span class="s4">&quot;nw&quot;</span><span class="s0">, </span><span class="s1">image=self.character_photo)</span>

    <span class="s0">def </span><span class="s1">attackboss(self):</span>
        <span class="s1">char_grid_x = self.x // cell_width</span>
        <span class="s1">char_grid_y = self.y // cell_height</span>

        <span class="s0">for </span><span class="s1">boss </span><span class="s0">in </span><span class="s1">boss_list[:]:</span>
            <span class="s1">boss_grid_x = boss.x // cell_width</span>
            <span class="s1">boss_grid_y = boss.y // cell_height</span>

            <span class="s0">if </span><span class="s1">char_grid_x == boss_grid_x </span><span class="s0">and </span><span class="s1">char_grid_y == boss_grid_y:</span>
                <span class="s0">if </span><span class="s1">self.grade &gt;= boss.grade:</span>
                    <span class="s1">boss_list.remove(boss)</span>
                    <span class="s1">boss.delete_from_canvas(canvas)</span>
                    <span class="s1">self.grade += </span><span class="s2">1</span>
                    <span class="s1">new_boss = generate_random_boss(self.grade)</span>
                    <span class="s1">new_boss.create_on_canvas(canvas)</span>
                    <span class="s1">boss_list.append(new_boss)</span>
                <span class="s0">else</span><span class="s1">:</span>
                    <span class="s1">self.grade = max(</span><span class="s2">0</span><span class="s0">, </span><span class="s1">self.grade - </span><span class="s2">1</span><span class="s1">)</span>
                <span class="s1">self.update_image()</span>
                <span class="s1">canvas.itemconfig(self.character_image_item</span><span class="s0">, </span><span class="s1">image=self.character_photo)</span>
                <span class="s0">break</span>


<span class="s0">class </span><span class="s1">Boss:</span>
    <span class="s0">def </span><span class="s1">__init__(self</span><span class="s0">, </span><span class="s1">x</span><span class="s0">, </span><span class="s1">y</span><span class="s0">, </span><span class="s1">grade):</span>
        <span class="s1">self.x = x</span>
        <span class="s1">self.y = y</span>
        <span class="s1">self.grade = grade</span>
        <span class="s1">self.form = BOSS</span>
        <span class="s1">self.boss_image_item = </span><span class="s0">None</span>
        <span class="s1">self.update_image()</span>

    <span class="s0">def </span><span class="s1">update_image(self):</span>
        <span class="s1">boss_image = Image.open(self.form[self.grade])</span>
        <span class="s1">boss_image = boss_image.resize((cell_width</span><span class="s0">, </span><span class="s1">cell_height))</span>
        <span class="s1">self.Boss_photo = ImageTk.PhotoImage(boss_image)</span>

    <span class="s0">def </span><span class="s1">create_on_canvas(self</span><span class="s0">, </span><span class="s1">canvas):</span>
        <span class="s1">self.boss_image_item = canvas.create_image(self.x</span><span class="s0">, </span><span class="s1">self.y</span><span class="s0">, </span><span class="s1">anchor=</span><span class="s4">&quot;nw&quot;</span><span class="s0">, </span><span class="s1">image=self.Boss_photo)</span>

    <span class="s0">def </span><span class="s1">delete_from_canvas(self</span><span class="s0">, </span><span class="s1">canvas):</span>
        <span class="s1">canvas.delete(self.boss_image_item)</span>

    <span class="s0">def </span><span class="s1">move_randomly(self):</span>
        <span class="s0">if </span><span class="s1">random.random() &lt; </span><span class="s2">0.1</span><span class="s1">:</span>
            <span class="s1">directions = [</span><span class="s4">&quot;Up&quot;</span><span class="s0">, </span><span class="s4">&quot;Down&quot;</span><span class="s0">, </span><span class="s4">&quot;Left&quot;</span><span class="s0">, </span><span class="s4">&quot;Right&quot;</span><span class="s1">]</span>
            <span class="s1">new_x</span><span class="s0">, </span><span class="s1">new_y = self.x</span><span class="s0">, </span><span class="s1">self.y</span>
            <span class="s1">dir = random.choice(directions)</span>

            <span class="s0">if </span><span class="s1">dir == </span><span class="s4">&quot;Up&quot; </span><span class="s0">and </span><span class="s1">self.y &gt; </span><span class="s2">0</span><span class="s1">:</span>
                <span class="s1">new_y -= cell_height</span>
            <span class="s0">elif </span><span class="s1">dir == </span><span class="s4">&quot;Down&quot; </span><span class="s0">and </span><span class="s1">self.y &lt; (rows - </span><span class="s2">1</span><span class="s1">) * cell_height:</span>
                <span class="s1">new_y += cell_height</span>
            <span class="s0">elif </span><span class="s1">dir == </span><span class="s4">&quot;Left&quot; </span><span class="s0">and </span><span class="s1">self.x &gt; </span><span class="s2">0</span><span class="s1">:</span>
                <span class="s1">new_x -= cell_width</span>
            <span class="s0">elif </span><span class="s1">dir == </span><span class="s4">&quot;Right&quot; </span><span class="s0">and </span><span class="s1">self.x &lt; (cols - </span><span class="s2">1</span><span class="s1">) * cell_width:</span>
                <span class="s1">new_x += cell_width</span>

            <span class="s3"># 更新位置</span>
            <span class="s1">self.x</span><span class="s0">, </span><span class="s1">self.y = new_x</span><span class="s0">, </span><span class="s1">new_y</span>
            <span class="s1">canvas.coords(self.boss_image_item</span><span class="s0">, </span><span class="s1">self.x</span><span class="s0">, </span><span class="s1">self.y)</span>


<span class="s0">def </span><span class="s1">generate_random_boss(current_level):</span>
    <span class="s1">level = random.randint(</span><span class="s2">0</span><span class="s0">, </span><span class="s1">min(current_level</span><span class="s0">, </span><span class="s2">5</span><span class="s1">))  </span><span class="s3"># 不超过最高等级</span>
    <span class="s1">x = random.randint(</span><span class="s2">0</span><span class="s0">, </span><span class="s1">cols - </span><span class="s2">1</span><span class="s1">) * cell_width</span>
    <span class="s1">y = random.randint(</span><span class="s2">0</span><span class="s0">, </span><span class="s1">rows - </span><span class="s2">1</span><span class="s1">) * cell_height</span>
    <span class="s0">return </span><span class="s1">Boss(x</span><span class="s0">, </span><span class="s1">y</span><span class="s0">, </span><span class="s1">level)</span>


<span class="s0">def </span><span class="s1">update_game():</span>
    <span class="s3"># 更新Boss状态</span>
    <span class="s0">for </span><span class="s1">boss </span><span class="s0">in </span><span class="s1">boss_list:</span>
        <span class="s1">boss.move_randomly()</span>

    <span class="s3"># 更新子弹状态</span>
    <span class="s0">for </span><span class="s1">zidan </span><span class="s0">in </span><span class="s1">zidan_list[:]:</span>
        <span class="s0">if not </span><span class="s1">zidan.is_alive:</span>
            <span class="s1">canvas.delete(zidan.image_item)</span>
            <span class="s1">zidan_list.remove(zidan)</span>
        <span class="s0">else</span><span class="s1">:</span>
            <span class="s1">zidan.run()</span>
            <span class="s1">zidan.attackboss()</span>

    <span class="s1">root.after(</span><span class="s2">50</span><span class="s0">, </span><span class="s1">update_game)  </span><span class="s3"># 提高游戏更新频率，使子弹更流畅</span>


<span class="s3"># 初始化游戏窗口</span>
<span class="s1">root = tk.Tk()</span>
<span class="s1">root.title(</span><span class="s4">&quot;Monster World&quot;</span><span class="s1">)</span>

<span class="s3"># 游戏参数</span>
<span class="s1">rows</span><span class="s0">, </span><span class="s1">cols = </span><span class="s2">9</span><span class="s0">, </span><span class="s2">9</span>
<span class="s1">cell_width = cell_height = </span><span class="s2">100</span>

<span class="s3"># 创建画布</span>
<span class="s1">canvas = tk.Canvas(root</span><span class="s0">, </span><span class="s1">width=cols * cell_width</span><span class="s0">, </span><span class="s1">height=rows * cell_height)</span>
<span class="s1">canvas.pack()</span>

<span class="s3"># 加载背景</span>
<span class="s1">background_image = Image.open(</span><span class="s4">&quot;F:/python2048/背景.jpg&quot;</span><span class="s1">)</span>
<span class="s1">background_image = background_image.resize((cols * cell_width</span><span class="s0">, </span><span class="s1">rows * cell_height))</span>
<span class="s1">background_photo = ImageTk.PhotoImage(background_image)</span>
<span class="s1">canvas.create_image(</span><span class="s2">0</span><span class="s0">, </span><span class="s2">0</span><span class="s0">, </span><span class="s1">anchor=</span><span class="s4">&quot;nw&quot;</span><span class="s0">, </span><span class="s1">image=background_photo)</span>

<span class="s3"># 创建角色</span>
<span class="s1">character_form = [</span>
    <span class="s4">&quot;F:/python2048/角色.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/角色1.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/角色2.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/角色3.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/角色4.jpg&quot;</span><span class="s0">,</span>
    <span class="s4">&quot;F:/python2048/终极角色.jpg&quot;</span>
<span class="s1">]</span>
<span class="s1">character_p1 = Character(</span><span class="s2">0</span><span class="s0">, </span><span class="s2">0</span><span class="s0">, </span><span class="s1">character_form)</span>

<span class="s3"># 初始化Boss</span>
<span class="s1">boss_list = [generate_random_boss(</span><span class="s2">0</span><span class="s1">) </span><span class="s0">for </span><span class="s1">_ </span><span class="s0">in </span><span class="s1">range(</span><span class="s2">3</span><span class="s1">)]</span>
<span class="s0">for </span><span class="s1">boss </span><span class="s0">in </span><span class="s1">boss_list:</span>
    <span class="s1">boss.create_on_canvas(canvas)</span>

<span class="s3"># 绑定事件</span>
<span class="s1">canvas.bind(</span><span class="s4">&quot;&lt;Button-1&gt;&quot;</span><span class="s0">, </span><span class="s1">on_canvas_click)</span>
<span class="s1">root.bind(</span><span class="s4">&quot;&lt;w&gt;&quot;</span><span class="s0">, </span><span class="s1">character_p1.move)</span>
<span class="s1">root.bind(</span><span class="s4">&quot;&lt;s&gt;&quot;</span><span class="s0">, </span><span class="s1">character_p1.move)</span>
<span class="s1">root.bind(</span><span class="s4">&quot;&lt;a&gt;&quot;</span><span class="s0">, </span><span class="s1">character_p1.move)</span>
<span class="s1">root.bind(</span><span class="s4">&quot;&lt;d&gt;&quot;</span><span class="s0">, </span><span class="s1">character_p1.move)</span>

<span class="s3"># 启动游戏循环</span>
<span class="s1">update_game()</span>
<span class="s1">root.mainloop()</span>
</pre>
</body>
</html>